package utils

import (
	"bytes"
	"fmt"
	"math/big"
)

var b58 = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")

// base58 编码
func Base58Encoding(src string) string {
	fmt.Println(len(b58))
	// he    h -> ascill 104   b -> 101    hex  十进制       104*256 + 101    = 26725
	// base58     --->>   26725 / 58 = 1 2 3(取余数)  0 1 3  ---> 13
	// 104 * 256 + 101 * 256 + x
	// 1. ascii 码对应的值
	src_byte := []byte(src)
	fmt.Println(src_byte)

	//2. 转成10进制
	i := big.NewInt(0).SetBytes(src_byte)
	fmt.Println(i)

	var mod_slice []byte
	for i.Cmp(big.NewInt(0)) > 0 {
		mod := big.NewInt(0)
		// 取余
		i58 := big.NewInt(58)
		i.DivMod(i, i58, mod)
		mod_slice = append(mod_slice, b58[mod.Int64()]) // 修改这里：将byte值添加到[]byte切片
	}

	fmt.Println("===============")
	// 将余数添加到数组中
	fmt.Println(mod_slice)

	// 把0使用字节 ‘1’ 代替
	for _, s := range src_byte {
		if s != 0 {
			break
		} else {
			mod_slice = append(mod_slice, byte('1')) // 修改这里：将byte值添加到[]byte切片
		}
	}
	// 需要反转 mod_slice，因为我们从低位到高位进行编码
	//for i, j := 0, len(mod_slice)-1; i < j; i, j = i+1, j-1 {
	//	mod_slice[i], mod_slice[j] = mod_slice[j], mod_slice[i]
	//}
	fmt.Println("===============")
	fmt.Println(mod_slice)
	fmt.Println(string(mod_slice))

	// 反转
	//a := []byte{56, 119, 110}
	//fmt.Println(string(a))
	// byte 数组进行翻转

	//ret_mode_slice := ReverseByteArr(mod_slice)

	ret_mode_slice2 := ReverseByteArr2(mod_slice)
	return string(ret_mode_slice2)

}

// byte数组进行翻转
func ReverseByteArr(b []byte) []byte {
	for i := 0; i < len(b)/2; i++ {
		b[i], b[len(b)-1-i] = b[len(b)-1-i], b[i]
	}
	return b
}

// byte 数组进行反转
func ReverseByteArr2(b []byte) []byte {
	for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
		b[i], b[j] = b[j], b[i]
	}
	return b
}

// base58解码
func Base58Decoding(src string) string {
	src_byte := []byte(src)
	fmt.Println(src_byte)

	ret := big.NewInt(0)
	for _, b := range src_byte {
		fmt.Print(b, ' ')
		i := bytes.IndexByte(b58, b)
		fmt.Println(i)
		ret.Mul(ret, big.NewInt(58))
		ret.Add(ret, big.NewInt(int64(i)))
	}

	fmt.Println(ret) // 26725

	fmt.Println(ret.Bytes())
	return string(ret.Bytes())

}
